package com.cryptoneedle.garden.service.garden.source.metadata;


import com.bubbles.engine.data.core.repository.BaseRepository;
import com.bubbles.engine.data.core.service.BaseService;
import com.cryptoneedle.garden.entity.source.metadata.SourceCatalog;
import com.cryptoneedle.garden.entity.source.metadata.SourceServer;
import com.cryptoneedle.garden.key.source.metadata.ServerKey;
import com.cryptoneedle.garden.repository.source.metadata.SourceCatalogRepository;
import com.cryptoneedle.garden.service.crud.garden.source.*;
import com.cryptoneedle.garden.service.garden.source.ConnectionService;
import com.cryptoneedle.garden.vo.CatalogSaveVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>description: 源数据源-目录 </p>
 *
 * @author CryptoNeedle
 * @date 2025-06-20
 */
@Slf4j
@Service
public class CatalogService extends BaseService<SourceCatalog, String> {

    @Lazy
    @Resource
    private CatalogService catalogService;
    @Resource
    private SourceCatalogRepository sourceCatalogRepository;

    @Override
    public BaseRepository<SourceCatalog, String> getRepository() {
        return sourceCatalogRepository;
    }

    @Autowired
    private FoundSourceService select;
    @Autowired
    private AddSourceService add;
    @Autowired
    private PatchSourceService patch;
    @Autowired
    private SaveSourceService save;
    @Autowired
    private DeleteSourceService delete;

    @Resource
    private ConnectionService connectionService;
    @Resource
    private DatabaseService databaseService;

    @Transactional
    public void addVo(CatalogSaveVo vo) {
        SourceServer originServer;
        SourceServer server;
        SourceCatalog catalog;

        // 参数
        if (StringUtils.isBlank(vo.getCatalogName())) {
            throw new RuntimeException("[Source] 目录名称不能为空");
        }
        if (StringUtils.isBlank(vo.getDorisCatalogName())) {
            throw new RuntimeException("[Source] Doris目录名称不能为空");
        }

        // 目录名称唯一
        catalog = select.catalog(vo.getCatalogName());
        if (catalog != null) {
            throw new RuntimeException("[Source] 目录名称已存在 => " + catalog.getCatalogName());
        }

        // Doris目录名称唯一
        catalog = select.catalogByDorisCatalogName(vo.getDorisCatalogName());
        if (catalog != null) {
            throw new RuntimeException("[Source] Doris目录名称冲突 => " + catalog.getCatalogName());
        }

        // SourceServer
        originServer = select.server(new ServerKey(vo.getHost(), vo.getPort()));
        if (originServer == null) {
            server = vo.createServer();
        } else {
            server = originServer;
        }

        // SourceCatalog
        catalog = vo.createCatalog();
        catalog.setServerConnected(server.getServerConnected());
        catalog.setServerConnectedDt(server.getServerConnectedDt());

        // 测试
        connectionService.testCatalog(catalog);

        // 保存
        save.save(server);
        save.save(catalog);

        // 清空Server
        delete.serversClean();

        // 同步数据库信息
        if (catalog.getJdbcConnected()) {
            databaseService.syncDatabase(catalog);
        }
    }

    @Transactional
    public void saveVo(CatalogSaveVo vo) {
        SourceServer server;
        SourceCatalog catalog;

        // 参数
        if (StringUtils.isBlank(vo.getCatalogName())) {
            throw new RuntimeException("[Source] 目录名称不能为空");
        }
        if (StringUtils.isBlank(vo.getDorisCatalogName())) {
            throw new RuntimeException("[Source] Doris目录名称不能为空");
        }

        // 目录名称唯一
        catalog = select.catalog(vo.getCatalogName());
        if (catalog == null) {
            throw new RuntimeException("[Source] 目录名称不存在 => " + vo.getCatalogName() + " (" + vo.getDorisCatalogName() + ")");
        }

        // Doris目录名称唯一
        SourceCatalog dorisCatalog = select.catalogByDorisCatalogName(vo.getDorisCatalogName());
        if (dorisCatalog != null && !Strings.CS.equals(dorisCatalog.getCatalogName(), vo.getCatalogName())) {
            throw new RuntimeException("[Source] Doris目录名称冲突 => " + dorisCatalog.getCatalogName());
        }

        // SourceServer
        server = select.server(new ServerKey(vo.getHost(), vo.getPort()));
        if (server == null) {
            server = vo.createServer();
        }

        // SourceCatalog
        SourceCatalog saveCatalog = vo.createCatalog();
        if (StringUtils.isNotBlank(saveCatalog.getHost())) {
            catalog.setHost(saveCatalog.getHost());
        }
        if (saveCatalog.getPort() != null) {
            catalog.setPort(saveCatalog.getPort());
        }
        if (saveCatalog.getDatabaseType() != null) {
            catalog.setDatabaseType(saveCatalog.getDatabaseType());
        }
        if (StringUtils.isNotBlank(saveCatalog.getRoute())) {
            catalog.setRoute(saveCatalog.getRoute());
        }
        if (StringUtils.isNotBlank(saveCatalog.getUserName())) {
            catalog.setUserName(saveCatalog.getUserName());
        }
        if (StringUtils.isNotBlank(saveCatalog.getPassword())) {
            catalog.setPassword(saveCatalog.getPassword());
        }
        if (saveCatalog.getConnectType() != null) {
            catalog.setConnectType(saveCatalog.getConnectType());
        }
        if (StringUtils.isNotBlank(saveCatalog.getDorisCatalogName())) {
            catalog.setDorisCatalogName(saveCatalog.getDorisCatalogName());
        }
        if (StringUtils.isNotBlank(saveCatalog.getDefaultSystemCode())) {
            catalog.setDefaultSystemCode(saveCatalog.getDefaultSystemCode());
        }

        // 测试
        connectionService.testCatalog(catalog);

        // 保存
        save.save(server);
        save.save(catalog);

        // 清空Server
        delete.serversClean();

        // 同步数据库信息
        if (catalog.getJdbcConnected()) {
            databaseService.syncDatabase(catalog);
        }
    }
}